import {
    useEffect,
    useRef,
    useState,
    type CSSProperties,
    type ReactNode,
} from "react";
import {
    Button,
    ConfigProvider,
    Flex,
    Input,
    Pagination,
    Row,
    Select,
    Table,
    type PaginationProps,
} from "antd";
import { Form } from "antd";
import locale from "antd/lib/locale/zh_CN";
import styles from "./index.module.scss";
import ResizableTitle from "./resizableTitle"; // 可拖拽表头组件
import React from "react";

interface FormProps {
    initsearchEnable?: boolean; // 初始化是否执行搜索(发送请求) 默认发送
    defaultPayload?: any; // 默认请求参数,每次都传给后台{xxxx:123}
    searchFields?: {
        // 搜索字段配置
        name: string; // 键
        label: string; // label
        allowClear?: boolean; // 是否允许清空
        width?: number; // 宽度
        defaultValue?: any; // 默认值
        placeholder?: string; // 占位符
        options?: {
            label?: string; // 显示的文本
            value?: any; // 值
        }[];
        style?: CSSProperties; // 样式
        render?: () => ReactNode; // 自定义渲染
    }[];
    formValues?: any; // 搜索表单值
    onSearch?: (values: any) => void; // 搜索事件
    onShowAddModal?: () => void; // 显示添加弹窗事件
}

type DataSource = {
    pageNum?: number;
    pageSize?: number;
    total?: number;
    totalPage?: number;
    list: any[];
};

interface TableProps {
    columns: any[]; // 表头配置
    rowKey?: string; // 行key
    data: DataSource; // table列表数据源
    paginationByFrontend?: boolean; // 是否前端分页
    orderColVisible?: boolean; // 是否显示排序 默认显示
    noPagination?: boolean; // 是否显示分页 默认显示
    selectedRowKeys?: any[]; // 选中的行key
    onSelectChange?: (keys: any[]) => void; // 选中行改变事件
    onRowSelect?: (
        record: any,
        selected: boolean,
        selectedRows: any[],
        nativeEvent: any
    ) => void; // 行选中事件
    onRowSelectAll?: (
        selected: boolean,
        selectedRows: any[],
        changeRows: any[]
    ) => void; // 全选事件
    getCheckboxProps?: (record: any) => any; // 获取多选框属性
    width?: number; // 表格宽度
    height?: number; // 表格高度
    isDragHeader?: boolean; // 是否可拖拽表头
}

interface actionProps {
    actionButtons?: any[]; // 操作按钮
}

interface Props {
    searchSectionConfig: FormProps;
    tableSectionConfig: TableProps;
    actionSectionConfig?: actionProps;
    paginationSectionConfig?: PaginationProps;
    wrapStyle?: CSSProperties;
    paginationStyle?: CSSProperties;
}

const WrapPageTable = (props: Props) => {
    const { searchSectionConfig, actionSectionConfig, tableSectionConfig } =
        props;
    const { height, isDragHeader, columns } = tableSectionConfig;
    const [newColumns, setNewColumns] = useState<any[]>(columns);
    const [form] = Form.useForm();
    const [selectedRowKeys, setSelectedRowKeys] = useState<any[]>([]);
    const wrapRef = useRef<any>(null);
    const searchRef = useRef<any>(null); // 搜索内容区域
    const actionRef = useRef<any>(null); // 操作按钮区域
    const dataRef = useRef<any>(null);
    const [restHeight, setReistHeight] = useState(!height ? 0 : height);
    const [dataState, setDataState] = useState<DataSource>({
        pageNum: 1,
        pageSize: 10,
        total: 0,
        list: [],
    });

    // 自动设置table的scrollY
    const autoTableY = () => {
        // 获取tab页面content高度
        const contentHeight = document.getElementsByClassName(
            "ant-tabs-content-holder"
        )[0].clientHeight;
        const parentNodeOffsetHeight =
            wrapRef.current?.parentNode?.offsetHeight || 0;
        const searchOffsetHeight = searchRef.current?.offsetHeight || 0;
        const actionOffsetHeight = actionRef.current?.offsetHeight || 0;

        const restHeightTemp =
            contentHeight - searchOffsetHeight - actionOffsetHeight - 154;
        console.log(
            contentHeight,
            searchOffsetHeight,
            actionOffsetHeight,
            restHeightTemp
        );

        setReistHeight(restHeightTemp);
    };

    // 处理 请求参数
    const hanleAllPayload = async (
        pageNum: number = 1,
        pageSize: number = 10
    ) => {
        const { defaultPayload, onSearch } = searchSectionConfig;
        const values = await form.validateFields(); // 获取表单值
        const res = Object.assign({}, defaultPayload, values, {
            pageNum,
            pageSize,
        }); // 合并默认值和表单值
        console.log("请求参数", res);
        onSearch?.(res);
    };

    // 搜索
    const handleSearch = () => {
        if (searchSectionConfig.searchFields?.length == 0) return;
        hanleAllPayload(1, 10); // 发送请求
    };

    // 重置搜索
    const handleReset = () => {
        form.resetFields(); // 重置表单
        hanleAllPayload(1, 10); // 发送请求
    };

    // 前端分页方法
    const handlePaginationByFrontend = (pageNum: number, pageSize: number) => {
        const list = [...dataRef.current.list];
        const total = list.length;
        const dataSource = list.slice((pageNum - 1) * pageSize, pageNum * pageSize);
        setDataState({
            total,
            list: dataSource,
            pageNum,
            pageSize,
        });
    };

    const { searchFields } = searchSectionConfig;

    // 分页参数变化
    const handlePageChange = (page: number, pageSize: number) => {
        const { paginationByFrontend } = tableSectionConfig;
        if (paginationByFrontend) {
            handlePaginationByFrontend(page, pageSize); // 前端分页
        } else {
            hanleAllPayload(page, pageSize); // 发送请求
        }
    };

    /**
     * 选中项发生变化时回调
     * @param selectedRowKeys 选中项的key
     * @param selectedRows 选中项
     */
    const handleSelectChange = (
        selectedRowKeys: React.Key[],
        selectedRows: any[]
    ) => {
        const { onSelectChange } = tableSectionConfig;
        setSelectedRowKeys(selectedRowKeys); // 设置选中的行key
        onSelectChange?.(selectedRowKeys); // 调用回调函数
    };

    /**
     * 用户手动选择/取消选择所有行的回调
     * @param selected 选中状态
     * @param selectedRows 选中的行
     * @param changeRows 变化的行
     */
    const handleRowSelectAll = (
        selected: boolean,
        selectedRows: any[],
        changeRows: any[]
    ) => {
        const { onRowSelectAll } = tableSectionConfig;
        // setSelectedRowKeys(selectedRows.map((row) => row.key)); // 设置选中的行key
        onRowSelectAll?.(selected, selectedRows, changeRows); // 调用回调函数
    };

    /**
     * 用户手动选择/取消选择某一行的回调
     * @param record 选中的行
     * @param selected 选中状态
     * @param selectedRows 选中的行
     * @param nativeEvent 原生事件
     */
    const handleRowSelect = (
        record: any,
        selected: boolean,
        selectedRows: any[],
        nativeEvent: any
    ) => {
        const { onRowSelect } = tableSectionConfig;
        // setSelectedRowKeys(selectedRows.map((row) => row.key)); // 设置选中的行key
        onRowSelect?.(record, selected, selectedRows, nativeEvent); // 调用回调函数
    };

    // 监听数据
    useEffect(() => {
        if (!tableSectionConfig.selectedRowKeys) {
            setSelectedRowKeys([]);
        }
        const { paginationByFrontend } = tableSectionConfig;
        dataRef.current = { ...tableSectionConfig.data };

        if (paginationByFrontend) {
            handlePaginationByFrontend(1, 10);
        } else {
            setDataState(dataRef.current);
        }
    }, [tableSectionConfig.data]);

    // 监听table选择的key
    useEffect(() => {
        const keys = tableSectionConfig.selectedRowKeys || []; // 获取选中的行key
        setSelectedRowKeys(keys); // 设置选中的行key
    }, [tableSectionConfig.selectedRowKeys]);

    // 监听搜索的form表达的值
    useEffect(() => {
        const values = searchSectionConfig.formValues || {}; // 获取表单值
        form.setFieldsValue(values); // 设置表单值
    }, [searchSectionConfig.formValues]);

    // 初始化加载
    useEffect(() => {
        const { height } = tableSectionConfig;
        const initsearchEnable = searchSectionConfig.initsearchEnable || true; // 是否初始化加载
        if (initsearchEnable) {
            hanleAllPayload(1, 10); // 发送请求
        }

        if (searchFields && searchFields.length > 0) {
            const initValues = searchFields?.reduce((prev: any, curr: any) => {
                if (curr.options && curr.defaultValue != undefined) {
                    prev[curr.name] = curr.defaultValue;
                }
                return prev;
            }, {});
            if (Object.keys(initValues).length > 0) {
                form.setFieldsValue(initValues);
            }
        }

        if (!height) {
            autoTableY();
        }
    }, []);

    // 初始化的时候 设置列
    useEffect(() => {
        let cols = columns;

        function loop(data: any) {
            data.map((item: any, index: number) => {
                if (!item.children) {
                    item.onHeaderCell = (column: any) => ({
                        width: column.width,
                        key: column.dataIndex,
                        onResize: handleResize(column),
                    });
                } else loop(item.children);
            });
        }
        loop(cols);
        setNewColumns(cols);
    }, [columns]);

    // 生成搜索条件和重置按钮
    const createSearchBtnGroup = () => {
        const btns = (
            <Flex gap={10}>
                <Button type="primary" onClick={handleSearch}>
                    搜索
                </Button>
                <Button onClick={handleReset}>重置</Button>
            </Flex>
        );
        return btns;
    };

    // 生成搜索条件
    const createFields = () => {
        const { searchFields } = searchSectionConfig; // 搜索字段配置
        if (!searchFields) {
            return null;
        }
        let fields = [];
        for (let i = 0; i < searchFields.length; i++) {
            const field = searchFields[i];
            const formItemStyle = field.style || { width: field.width || 200 };
            fields.push(
                <Form.Item key={field.name} name={field.name} label={field.label}>
                    {field.render ? (
                        field.render()
                    ) : field.options ? (
                        <Select
                            style={formItemStyle}
                            allowClear
                            placeholder={field.placeholder ?? `请选择${field.label}`}
                            defaultValue={field.defaultValue}
                            options={field.options}
                        ></Select>
                    ) : (
                        <Input
                            style={formItemStyle}
                            allowClear
                            placeholder={field.placeholder ?? `请输入${field.label}`}
                            defaultValue={field.defaultValue}
                        />
                    )}
                </Form.Item>
            );
        }
        return <Row>{fields}</Row>;
    };

    // 生成操作按钮
    const createActionBtn = () => {
        if (!actionSectionConfig) return null;
        const { actionButtons } = actionSectionConfig; // 操作按钮配置
        if (!actionButtons) {
            return null;
        }
        const children: ReactNode[] = []; // 操作按钮
        actionButtons.map((item, index) => {
            children.push(React.cloneElement(item.render(), { key: index }));
        });
        return children;
    };

    // 提取列处理逻辑
    const processColumn = (item: any) => {
        item.ellipsis = item.ellipsis !== undefined ? item.ellipsis : true;
        if (isDragHeader) {
            item.onHeaderCell = (column: any) => {
                return {
                    width: column.width,
                    key: column.dataIndex,
                    onResize: handleResize(column),
                };
            };
        }
        return item;
    };

    // 处理table列
    const handleColumns = (cols: any[]) => {
        const processedCols = cols.map(processColumn);

        if (
            processedCols[0]?.title !== "序号" &&
            !!tableSectionConfig.orderColVisible
        ) {
            processedCols.unshift({
                title: "序号",
                dataIndex: "seq",
                key: "seq",
                fixed: "left",
                width: 60,
                render: (text: any, record: any, index: number) => {
                    const currentPage = dataState.pageNum || 1;
                    const pageSize = dataState.pageSize || 10;
                    return pageSize * (currentPage - 1) + index + 1;
                },
            });
        }

        return processedCols;
    };

    // 拖拽方法
    const handleResize =
        (info: any) =>
            (e: any, { size }: any) => {
                const updatedColumns = newColumns.map((col) => {
                    if (col.dataIndex === info.dataIndex) {
                        return { ...col, width: size.width };
                    }
                    return col;
                });
                setNewColumns(updatedColumns);
            };

    const wrapStyle = props.wrapStyle || {}; // 外层样式
    const paginationStyle = props.paginationStyle || {}; // 分页样式

    const render = () => {
        const { width, onSelectChange, getCheckboxProps, noPagination } =
            tableSectionConfig;
        let total = 0,
            pageNum = 1,
            pageSize = 10,
            totalPage = 0,
            dataSource = [];
        if (dataState) {
            total = dataState.total || total; // 总条数
            pageNum = dataState.pageNum || pageNum; // 当前页码
            pageSize = dataState.pageSize || pageSize; // 每页条数
            totalPage = Math.ceil(total / pageSize); // 总页数
            dataSource = dataState.list; // 分页数据
        }
        const lastNumber =
            pageNum == totalPage && total != pageSize ? total % pageSize : pageSize; // 最后一页的条数
        const startPageNumber = total != 0 ? (pageNum - 1) * pageSize + 1 : 0; // 开始页码
        const endPageNumber =
            total != 0 ? (pageNum - 1) * pageSize + lastNumber : 0; // 结束页码

        /* 内置rowSelect设置 */
        const innerRowSelection = {
            selectedRowKeys,
            onChange: handleSelectChange,
            onSelectAll: handleRowSelectAll,
            onselect: handleRowSelect,
            getCheckboxProps: getCheckboxProps
                ? getCheckboxProps
                : (record: any) => ({ disabled: record.disabled == null }),
        };

        return (
            <section ref={wrapRef} style={wrapStyle}>
                <ConfigProvider locale={locale}>
                    <section ref={searchRef}>
                        {searchFields && searchFields.length > 0 ? (
                            <Flex wrap className={styles["table-search"]}>
                                <Form layout="inline" form={form} onFinish={handleSearch}>
                                    {createFields()}
                                </Form>
                                <div>{createSearchBtnGroup()}</div>
                            </Flex>
                        ) : null}
                    </section>
                    <section ref={actionRef}>
                        <Flex gap={10} wrap className={styles["table-action"]}>
                            {createActionBtn()}
                        </Flex>
                    </section>
                    <section>
                        <Table
                            {...tableSectionConfig}
                            columns={handleColumns(newColumns)}
                            rowSelection={onSelectChange && innerRowSelection}
                            dataSource={dataSource}
                            pagination={false}
                            components={{
                                header: {
                                    cell: isDragHeader ? ResizableTitle : undefined,
                                },
                            }}
                            scroll={{ x: width || 1200, y: restHeight }}
                        />
                        {!noPagination && (
                            <Flex
                                align="center"
                                justify="flex-end"
                                className={styles["table-pagination"]}
                            >
                                <span>
                                    {`显示第${startPageNumber}到${endPageNumber}条数据，共${total}条数据`}
                                </span>
                                <Pagination
                                    style={paginationStyle}
                                    total={total}
                                    current={pageNum}
                                    pageSize={pageSize}
                                    showSizeChanger
                                    showQuickJumper
                                    onChange={handlePageChange}
                                />
                            </Flex>
                        )}
                    </section>
                </ConfigProvider>
            </section>
        );
    };

    return render();
};

export default WrapPageTable;
